#ifndef FILE_H
#define FILE_H

#include "Types.h"

#define ELF_IDENTIFY        0x7F
#define PT_LOAD             1


/**
 * @brief ELF 文件头结构体
 *
 * 所有 ELF 文件都以一个 ELF 文件头开始，它描述了整个文件的组织方式。
 * 包括：
 * - 文件魔数识别
 * - 目标架构
 * - 入口地址
 * - 段表位置和数量等
 */
typedef struct {
    /**
     * 魔数和元信息
     * - e_ident[0] = 0x7F, e_ident[1~3] = 'E', 'L', 'F'
     * - 后续字节表示文件类（32/64位）、数据编码（大端/小端）、ELF 版本等
     */
    char e_ident[16];

    /**
     * 文件类型
     * - ET_NONE: 未指定
     * - ET_REL: 可重定位文件
     * - ET_EXEC: 可执行文件
     * - ET_DYN: 共享库
     * - ET_CORE: Core dump 文件
     */
    uint16_t e_type;

    /**
     * 目标机器类型
     * - EM_386: Intel 80386
     * - EM_MIPS: MIPS
     * - EM_ARM: ARM 等
     */
    uint16_t e_machine;

    /**
     * ELF 文件版本
     * 当前只支持 EV_CURRENT（值为1）
     */
    uint32_t e_version;

    /**
     * 入口地址（Entry Point）
     * 程序启动时 CPU 开始执行的虚拟地址
     */
    uint32_t e_entry;

    /**
     * 程序头表（Program Header Table）在文件中的偏移
     * 如果没有程序头表，则该值为0
     */
    uint32_t e_phoff;

    /**
     * 节区头表（Section Header Table）在文件中的偏移
     * 若不使用节区头表，可以设为0
     */
    uint32_t e_shoff;

    /**
     * 与处理器相关的标志
     * 通常用于特定平台的扩展标志
     */
    uint32_t e_flags;

    /**
     * ELF 文件头本身的大小（单位：字节）
     * 通常是 sizeof(Elf32_Ehdr)
     */
    uint16_t e_ehsize;

    /**
     * 程序头表中每个条目的大小（单位：字节）
     * 通常是 sizeof(Elf32_Phdr)
     */
    uint16_t e_phentsize;

    /**
     * 程序头表中条目数量
     * 即程序段的数量
     */
    uint16_t e_phnum;

    /**
     * 节区头表中每个条目的大小（单位：字节）
     * 通常是 sizeof(Elf32_Shdr)
     */
    uint16_t e_shentsize;

    /**
     * 节区头表中条目数量
     */
    uint16_t e_shnum;

    /**
     * 节区名字符串表在节区头表中的索引
     */
    uint16_t e_shstrndx;

} Elf32_Ehdr;


/**
 * @brief ELF 程序段头结构体
 *
 * 描述 ELF 文件中可加载段的信息，用于指导操作系统如何将程序段加载到内存。
 */
typedef struct {
    /**
     * 段类型
     * - PT_NULL: 未使用
     * - PT_LOAD: 可加载段（代码、数据等）
     * - PT_DYNAMIC: 动态链接信息
     * - PT_INTERP: 解释器路径名
     * - PT_NOTE: 辅助信息
     * - PT_SHLIB: 保留，未定义语义
     * - PT_PHDR: 段头表本身
     */
    uint32_t p_type;

    /**
     * 此段在文件中的起始偏移
     */
    uint32_t p_offset;

    /**
     * 此段在内存中的虚拟地址
     * 加载到内存后，该段的内容应位于此处
     */
    uint32_t p_vaddr;

    /**
     * 此段在内存中的物理地址
     * 在裸机系统中可能用到，一般情况下与 p_vaddr 相同
     */
    uint32_t p_paddr;

    /**
     * 此段在文件中的大小（单位：字节）
     * 即磁盘上占用的实际空间
     */
    uint32_t p_filesz;

    /**
     * 此段在内存中的大小（单位：字节）
     * 通常 >= p_filesz，多出部分会初始化为0
     */
    uint32_t p_memsz;

    /**
     * 段的标志位
     * - PF_X: 可执行权限
     * - PF_W: 可写权限
     * - PF_R: 可读权限
     */
    uint32_t p_flags;

    /**
     * 内存对齐要求
     * 在文件和内存中都必须满足这个对齐要求
     */
    uint32_t p_align;

} Elf32_Phdr;


#endif